#Region "Imports"
Imports System.Collections.Generic
#End Region
''' <summary>
''' This class implements the page trees
''' </summary>
''' <remarks></remarks>
Friend Class clsPDFPageTree
#Region "Private members"
    Private _parent As clsPDFPageTree
    Private _childs As New List(Of clsPDFPageTree)
    Private _pageInfo As clsPDFPage
    Private _pageNumber As Integer  'only valid for leaf page node
    Private _objectNumber As Long
    Private _generationNumber As Long
#End Region
#Region "Constructors"
    Public Sub New()
        _pageNumber = -1
    End Sub
#End Region
#Region "Public Properties"
    Public Property PageNumber() As Integer
        Get
            PageNumber = _pageNumber
        End Get
        Set(ByVal value As Integer)
            _pageNumber = value
        End Set
    End Property
    Public ReadOnly Property IsLeafPage() As Boolean
        Get
            'We have a leaf page object if the page tree has no child
            'IsLeafPage = (_childs.Count = 0)
            IsLeafPage = (_pageInfo.Item(PDF_TYPE).GetString = PDF_PAGE)
        End Get
    End Property
    Public Property PageInformationDictionnary() As clsPDFPage
        Get
            PageInformationDictionnary = _pageInfo
        End Get
        Set(ByVal value As clsPDFPage)
            _pageInfo = value
            _pageInfo.Parent = Me
        End Set
    End Property
    Public Property Parent() As clsPDFPageTree
        Get
            Parent = _parent
        End Get
        Set(ByVal value As clsPDFPageTree)
            _parent = value
        End Set
    End Property
#End Region
#Region "Public Methods"
    ''' <summary>
    ''' Get the pdf base object of an attribute, we look at the parents if not found
    ''' in the current tree
    ''' </summary>
    ''' <param name="attribute"></param>
    ''' <returns></returns>
    ''' <remarks>Some page's attribute can be inherited</remarks>
    Public Function GetInheritedAttribute(ByVal attribute As String) As clsPdfBaseObject
        Dim obj As clsPdfBaseObject
        obj = _pageInfo.Item(attribute)
        If Not obj Is Nothing Then
            GetInheritedAttribute = obj
        Else
            'if the attribute is not found, we search it in the parent
            If Not Parent Is Nothing Then
                GetInheritedAttribute = Parent.GetInheritedAttribute(attribute)
            Else
                'The attribute was not found
                GetInheritedAttribute = Nothing
            End If
        End If

    End Function
    ''' <summary>
    ''' Get the page information dictionnary of a specific page number
    ''' </summary>
    ''' <param name="pageNumber"></param>
    ''' <returns></returns>
    ''' <remarks>If the current tree is not the page number we are looking for
    ''' we look at the childs recursively until we got at the bottom of the page tree.</remarks>
    Public Function GetPageInformation(ByVal pageNumber As Integer) As clsPDFPage
        Dim pageTree As clsPDFPageTree

        If _pageNumber = pageNumber Then
            GetPageInformation = _pageInfo
        Else
            If Not IsLeafPage Then
                For Each pageTree In _childs
                    GetPageInformation = pageTree.GetPageInformation(pageNumber)
                    If Not GetPageInformation Is Nothing Then
                        Exit Function
                    End If
                Next
                GetPageInformation = Nothing
            Else
                GetPageInformation = Nothing
            End If
        End If
    End Function
    ''' <summary>
    ''' Get all the images of the pagetree
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub GetImages(ByRef images As Dictionary(Of String, clsPDFImage))
        Dim pageTree As clsPDFPageTree
        Dim liste As List(Of clsPDFImage)
        Dim image As clsPDFImage

        For Each pageTree In _childs
            If pageTree.IsLeafPage Then
                liste = pageTree.PageInformationDictionnary.GetImages
                For Each image In liste
                    If Not images.ContainsKey(image.Name) Then
                        images.Add(image.Name, image)
                    End If
                Next
            Else
                pageTree.GetImages(images)
            End If
        Next
    End Sub
    Public Sub AddChild(ByVal child As clsPDFPageTree)
        child.Parent = Me
        _childs.Add(child)
    End Sub
#End Region
#Region "Friend Properties"
    ''' <summary>
    ''' Return all the pages' information object that has been modified
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend ReadOnly Property GetPagesModified() As List(Of clsPDFPage)
        Get
            Dim pagesList As New List(Of clsPDFPage)
            _pagesModified(Me, pagesList)
            GetPagesModified = pagesList
        End Get
    End Property
    Friend Property GenerationNumber() As Long
        Get
            GenerationNumber = _generationNumber
        End Get
        Set(ByVal value As Long)
            _generationNumber = value
        End Set
    End Property
    Friend Property ObjectNumber() As Long
        Get
            ObjectNumber = _objectNumber
        End Get
        Set(ByVal value As Long)
            _objectNumber = value
        End Set
    End Property
#End Region
#Region "Friend Methods"
    Friend Sub GetPageCount(ByRef pageCount As Long)
        Dim pageTree As clsPDFPageTree

        If Not IsLeafPage Then
            For Each pageTree In _childs
                pageTree.GetPageCount(pageCount)
            Next
        Else
            pageCount += 1
        End If
    End Sub
#End Region
#Region "Private Methods"
    ''' <summary>
    ''' Return all the pages that are modified, traverse all the page trees recursively
    ''' </summary>
    ''' <param name="pageTree"></param>
    ''' <param name="pagesList"></param>
    ''' <remarks></remarks>
    Private Sub _pagesModified(ByVal pageTree As clsPDFPageTree, ByRef pagesList As List(Of clsPDFPage))
        If pageTree.PageInformationDictionnary.Dirty Then
            pagesList.Add(pageTree.PageInformationDictionnary)
        End If
        Dim pTree As clsPDFPageTree
        For Each pTree In pageTree._childs
            _pagesModified(pTree, pagesList)
        Next
    End Sub
#End Region
End Class
